package com.campus.service.impl;


import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.campus.common.core.domain.AjaxResult;
import com.campus.mapper.UserMapper;
import com.campus.pojos.domain.ClientArticleLove;
import com.campus.pojos.domain.dto.PhoneAccountDto;
import com.campus.pojos.domain.dto.UserDto;
import com.campus.pojos.domain.dto.UserQueryDto;
import com.campus.pojos.domain.vo.UserVo;
import com.campus.result.PageResult;
import com.campus.result.Result;
import com.campus.service.ArticleLoveService;
import com.campus.service.UserService;
import com.campus.constant.JwtClaimsConstant;
import com.campus.pojos.domain.dto.UserAccountDto;
import com.campus.pojos.domain.ClientUser;
import com.campus.pojos.domain.vo.UserLoginVo;
import com.campus.properties.JwtProperties;
import com.campus.utils.JwtUtil;
import lombok.extern.slf4j.Slf4j;
import org.jetbrains.annotations.NotNull;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.data.redis.RedisProperties;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.DigestUtils;
import redis.clients.jedis.Jedis;

import java.time.LocalDateTime;
import java.util.*;
import java.util.stream.Collectors;


@Service
@Slf4j
@Transactional
public class UserServiceImpl extends ServiceImpl<UserMapper, ClientUser> implements UserService {

    @Autowired
    private JwtProperties jwtProperties;

    @Autowired UserMapper userMapper;
    /**
     * C端用户登录
     *
     * @param dto
     * @return
     */
    @Override
    public Result<UserLoginVo> login(UserAccountDto dto) {

        if( !StringUtils.isBlank(dto.getUserName()) && !StringUtils.isBlank(dto.getPassword())){
            //ClientUser user = userMapper.getById(dto.getUserName());
            ClientUser user = getOne(Wrappers.<ClientUser>lambdaQuery().eq(ClientUser::getUserName, dto.getUserName()));
            if(user == null){
                return Result.error("用户信息为空，请先注册");
            }
            if(user.getStatus() == 0){
                return Result.error("该用户被禁用，如有问题请联系管理员！");
            }
            String password = dto.getPassword();
            password = DigestUtils.md5DigestAsHex(password.getBytes());
            if(!password.equals(user.getPassword())){
                return Result.error("密码错误！");
            }
            //登录成功后，生成jwt令牌
            return getUserLoginVoResult(user);

        }else{
            return Result.error("用户名或密码为空！");
        }
    }

    /**
     * 手机号登录
     *
     * @param dto
     * @return
     */
    @Override
    public Result<UserLoginVo> loginByPhone(UserAccountDto dto) {
        if( !StringUtils.isBlank(dto.getPhone()) && !StringUtils.isBlank(dto.getCode())){
            //ClientUser user = userMapper.getById(dto.getUserName());
            ClientUser user = getOne(Wrappers.<ClientUser>lambdaQuery().eq(ClientUser::getPhone, dto.getPhone()));
            if(user == null){
                return Result.error("用户信息为空，请先注册");
            }
            //验证码验证
            String code = dto.getCode();
            String yzm = getYzm();
            if(!yzm.equals(code)){
                return Result.error(" 验证码错误！");
            }
            return getUserLoginVoResult(user);

        }else{
            return Result.error("用户名或密码为空！");
        }
    }



    @NotNull
    private Result<UserLoginVo> getUserLoginVoResult(ClientUser user) {
        //登录成功后，生成jwt令牌
        Map<String, Object> claims = new HashMap<>();
        claims.put(JwtClaimsConstant.EMP_ID, user.getId());
        String token = JwtUtil.createJWT(
                jwtProperties.getAdminSecretKey(),
                jwtProperties.getAdminTtl(),
                claims);

        //封装返回结果Vo
        UserLoginVo loginVo = new UserLoginVo();
        loginVo.setUserId(user.getId());
        loginVo.setUserName(user.getUserName());
        loginVo.setToken(token);
        return Result.success(loginVo);
    }

    /**
     * C端用户注册
     *
     * @param dto
     * @return
     */
    @Override
    public Result register(UserAccountDto dto) {
        //参数验证
        if( !StringUtils.isBlank(dto.getUserName()) && !StringUtils.isBlank(dto.getPassword())) {
            ClientUser user = new ClientUser();

            //MD5加密
            String password = dto.getPassword();
            password = DigestUtils.md5DigestAsHex(password.getBytes());

            //实体类存入数据库中
            user.setUserName(dto.getUserName());
            user.setPassword(password);
            user.setStatus(1);
            user.setCreateTime(LocalDateTime.now());
            user.setUpdateTime(LocalDateTime.now());
            save(user);

            //返回结果
            return Result.success();
        }else{
            //传来参数有误
            return Result.error("信息不全!");
        }
    }

    /**
     * 手机号注册
     *
     * @param dto
     * @return
     */
    @Override
    public Result registerByPhone(UserAccountDto dto) {
        //参数验证
        if( !StringUtils.isBlank(dto.getPhone()) && !StringUtils.isBlank(dto.getCode())) {
            ClientUser user = getOne(Wrappers.<ClientUser>lambdaQuery().eq(ClientUser::getPhone, dto.getPhone()));
            if(user != null){
                //该手机已经注册过
                return Result.error("该手机已被注册，请直接登录！");
            }

            user = new ClientUser();

            //验证码验证
            String yzm = getYzm();
            if(!yzm.equals(dto.getCode())) {
                return Result.error(" 验证码错误！");
            }
            //MD5加密
            String password = dto.getPassword();
            password = DigestUtils.md5DigestAsHex(password.getBytes());

            //实体类存入数据库中
            user.setUserName(dto.getPhone());
            user.setPhone(dto.getPhone());
            user.setPassword(password);
            user.setStatus(1);
            user.setCreateTime(LocalDateTime.now());
            user.setUpdateTime(LocalDateTime.now());
            save(user);

            //返回结果
            return Result.success();
        }else{
            //传来参数有误
            return Result.error("信息不全!");
        }
    }

    /**
     * 获取redis中存入的验证码
     * @return
     */
    private static String getYzm() {
        Jedis jedis = new Jedis("127.0.0.1", 6379);
        jedis.auth("123456");
        return jedis.get("code");
    }

    /**
     * 根据用户id查询用户信息
     *
     * @param id
     * @return
     */
    @Override
    public Result<UserVo> getByUserId(Long id) {
        ClientUser user = getById(id);
        //判读是否有该用户
        if(user == null){
            return Result.error("用户信息为空");
        }
        //分装Vo返回
        UserVo userVo = new UserVo();
        BeanUtils.copyProperties(user,userVo);
        //特殊处理
        userVo.setUserId(user.getId());

        return Result.success(userVo);
    }

    /**
     * 修改用户信息
     *
     * @param dto
     * @return
     */
    @Override
    public Result edit(UserDto dto) {
        //参数验证
        if(dto == null || dto.getUserId() == null) {
            return Result.error("userDto为空");
        }

        ClientUser user = new ClientUser();
        BeanUtils.copyProperties(dto, user);
        //处理密码
        if(dto.getPassword() != null) {
            user.setPassword(DigestUtils.md5DigestAsHex(dto.getPassword().getBytes()));
        }
        //补充缺少字段
        user.setUpdateTime(LocalDateTime.now());
        user.setId(dto.getUserId());
        //保存
        updateById(user);
        return Result.success();
    }

    @Autowired
    private ArticleLoveService articleLoveService;

    /**
     * 获取用户点赞帖子id集合
     *
     * @param id
     * @return
     */
    @Override
    public Result<List<Long>> getLove(Long id) {
        //1.验证参数
        ClientUser user = getById(id);
        if(user == null) {
            return Result.error("不存在该用户");
        }

        List<Long> ids = new ArrayList<>();
        //根据userId查询帖子点赞关系表
        QueryWrapper<ClientArticleLove> qw = new QueryWrapper<>();
        qw.eq("user_id", id);

        List<ClientArticleLove> loveList = articleLoveService.list(qw);
        if(loveList == null){
            //返回空的ids
            return Result.success(ids);
        }
        //封装点赞帖子的id
        ids = loveList.stream().map(ClientArticleLove::getArticleId).collect(Collectors.toList());

        return Result.success(ids);
    }

    public String getUserName(Long id){
        ClientUser user = getById(id);
        return user.getUserName();
    }

    /**
     * 用户条件查询
     *
     * @param dto
     * @return
     */
    @Override
    public AjaxResult queryList(UserQueryDto dto) {
        //1页码
        if(dto.getPage() == null ) dto.setPage(1);
        if(dto.getPageSize() == null) dto.setPageSize(10);
        IPage<ClientUser> page = new Page<>(dto.getPage(), dto.getPageSize());
        //2条件
        QueryWrapper<ClientUser> qw = new QueryWrapper<>();
        //2.1搜索框
        if(!StringUtils.isBlank(dto.getNickName())){
            qw.like("nick_name", dto.getNickName());
        }
        //2.2手机号
        if(!StringUtils.isBlank(dto.getPhone())){
            qw.like("phone",dto.getPhone());
        }
        //2.3状态
        if(dto.getStatus() != null){
            qw.eq("status", dto.getStatus());
        }
        //2.4时间
        if(dto.getEndTime()!= null && dto.getBeginTime() != null){
            qw.ge("create_time", dto.getBeginTime());
            qw.le("create_time", dto.getEndTime());
        }
        //2.5专业
        if(dto.getMajor() != null){
            qw.like("major", dto.getMajor());
        }
        page = userMapper.selectPage(page, qw);
        //3 封装返回
        List<ClientUser> users = page.getRecords();
        List<UserVo> records = new ArrayList<>();
        for(ClientUser clientUser : users){
            UserVo userVo = new UserVo();
            BeanUtils.copyProperties(clientUser, userVo);
            userVo.setUserId(clientUser.getId());
            records.add(userVo);
        }

        PageResult pageResult = new PageResult();
        pageResult.setTotal(page.getTotal());
        pageResult.setRecords(records);

        return AjaxResult.success("success",pageResult);
    }

    /**
     * 状态修改
     *
     * @param userId
     * @param status
     */
    @Override
    public void status(Long userId, Integer status) {
        ClientUser user = getById(userId);
        user.setStatus(status);
        updateById(user);
    }



}
